package com.list.task;

import com.alibaba.fastjson2.JSON;
import com.api.client.VideoClient;
import com.common.constant.RedisKey;
import com.common.domain.po.CollectRecord;
import com.common.domain.po.LikedRecord;
import com.common.domain.po.Video;
import com.common.utils.CollectUtils;
import com.list.mapper.CollectRecordMapper;
import com.list.mapper.LikedRecordMapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import org.springframework.cglib.core.Local;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author 路亚
 * @version 0.1
 * @className ListTask
 * @description
 * @date 2025/1/2 17:13
 * @since jdk11
 */
@Component
@RequiredArgsConstructor
public class ListTask {

    private final StringRedisTemplate stringRedisTemplate;

    private final LikedRecordMapper likedRecordMapper;

    private final CollectRecordMapper collectRecordMapper;

    private final VideoClient videoClient;

    /**
     * 把第二日的所有排行榜信息更新到redis 中
     */
    @XxlJob("listTask")
    public void listTask() {
        stringRedisTemplate.delete(RedisKey.LIST_HOT_RESULT_KEY);
        stringRedisTemplate.delete(RedisKey.LIST_SEARCH_RESULT_KEY);
        stringRedisTemplate.delete(RedisKey.LIST_SOAR_RESULT_KEY);
        // 整理需要用的到的数据
        String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String yesterday = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String todayLookNumKey = RedisKey.LIST_LOOK_NUM_KEY + today;
        String yesterdayLookNumKey = RedisKey.LIST_LOOK_NUM_KEY + yesterday;
        // 获取今日和昨日的所有短剧的观看次数
        Set<Object> todayKeys = stringRedisTemplate.opsForHash().keys(todayLookNumKey);
        if (todayKeys == null || todayKeys.size() == 0) {
            return;
        }
        Set<Object> yesterdayKeys = stringRedisTemplate.opsForHash().keys(yesterdayLookNumKey);
        if (yesterdayKeys == null || yesterdayKeys.size() == 0) {
            return;
        }
        Map<String, Integer> todayLookNumMap = new HashMap<>();
        Map<String, Integer> yesterdayLookNumMap = new HashMap<>();
        Map<String, Integer> searchNumMap = new HashMap<>();
        String searchKey = RedisKey.LIST_SEARCH_KEY + today;
        for (Object todayKey : todayKeys) {
            if (todayKey != null) {
                String key = todayKey.toString();
                Object o = stringRedisTemplate.opsForHash().get(todayLookNumKey, key);
                if (o != null) {
                    todayLookNumMap.put(key, Integer.parseInt(o.toString()));
                }
            }
        }
        for (Object yesterdayKey : yesterdayKeys) {
            if (yesterdayKey != null) {
                String key = yesterdayKey.toString();
                Object o = stringRedisTemplate.opsForHash().get(yesterdayLookNumKey, key);
                if (o != null) {
                    yesterdayLookNumMap.put(key, Integer.parseInt(o.toString()));
                }
            }
        }
        for (Object Key : stringRedisTemplate.opsForHash().keys(searchKey)){
            if (Key != null) {
                String key = Key.toString();
                Object o = stringRedisTemplate.opsForHash().get(searchKey, key);
                if (o != null) {
                    searchNumMap.put(key, Integer.parseInt(o.toString()));
                }
            }
        }
        // 获取昨日和今日的点赞数和收藏数
        List<LikedRecord> yesterdayLikedRecords = likedRecordMapper.selectByDate(Integer.parseInt(yesterday));
        List<LikedRecord> todayLikedRecords = likedRecordMapper.selectByDate(Integer.parseInt(today));
        List<CollectRecord> yesterdayCollectRecords = collectRecordMapper.selectByDate(Integer.parseInt(yesterday));
        List<CollectRecord> todayCollectRecords = collectRecordMapper.selectByDate(Integer.parseInt(today));
        // 短剧id 加 点赞数
        Map<Long, Integer> yesterdayLikedMap = new HashMap<>();
        Map<Long, Integer> todayLikedMap = new HashMap<>();
        // 短剧id 加 收藏数
        Map<Long, Integer> yesterdayCollectMap = new HashMap<>();
        Map<Long, Integer> todayCollectMap = new HashMap<>();
        for (LikedRecord yesterdayLikedRecord : yesterdayLikedRecords) {
            if (yesterdayLikedMap.get(yesterdayLikedRecord.getVideoId()) == null) {
                yesterdayLikedMap.put(yesterdayLikedRecord.getVideoId(), 1);
            } else {
                yesterdayLikedMap.put(yesterdayLikedRecord.getVideoId(), yesterdayLikedMap.get(yesterdayLikedRecord.getVideoId()) + 1);
            }
        }
        for (LikedRecord todayLikedRecord : todayLikedRecords) {
            if (todayLikedMap.get(todayLikedRecord.getVideoId()) == null) {
                todayLikedMap.put(todayLikedRecord.getVideoId(), 1);
            } else {
                todayLikedMap.put(todayLikedRecord.getVideoId(), todayLikedMap.get(todayLikedRecord.getVideoId()) + 1);
            }
        }
        for (CollectRecord yesterdayCollectRecord : yesterdayCollectRecords) {
            if (yesterdayCollectMap.get(yesterdayCollectRecord.getVideoId()) == null) {
                yesterdayCollectMap.put(yesterdayCollectRecord.getVideoId(), 1);
            } else {
                yesterdayCollectMap.put(yesterdayCollectRecord.getVideoId(), yesterdayCollectMap.get(yesterdayCollectRecord.getVideoId()) + 1);
            }
        }
        for (CollectRecord todayCollectRecord : todayCollectRecords) {
            if (todayCollectMap.get(todayCollectRecord.getVideoId()) == null) {
                todayCollectMap.put(todayCollectRecord.getVideoId(), 1);
            } else {
                todayCollectMap.put(todayCollectRecord.getVideoId(), todayCollectMap.get(todayCollectRecord.getVideoId()) + 1);
            }
        }
        /**
         * 需求：根据短剧的收藏、点赞、播放数量等维度，给短剧设置排行榜
         * ● 飙升榜：0.5×(昨天的收藏次数)+0.3×(昨天的点赞数)+0.2×(昨天的观看次数)
         * ● 热搜榜：0.4×(今天搜索次数)+0.3×(今天的收藏次数)+0.2×(今天的点赞数)+0.1*(今天的观看次数)
         * ● 热播榜、新剧榜：0.5×(收藏次数)+0.3×(点赞数)+0.2×(总观看次数)
         */
        // 飙升榜 key = videoId value = 飙升榜分数
        Map<Long, Double> soarMap = new HashMap<>();
        List<Video> videos = videoClient.queryIds();
        // 热搜榜
        Map<Long, Double> searchMap = new HashMap<>();
        // 热播棒
        /* TODO: 热播棒实现思路
             查询上架时间在一月之内的短剧信息，可以获取每个短剧的收藏总数
             根据每个短剧可以获取对应的短剧行信息，可以遍历获取短剧行的点赞总数
             总管看次数，从redis里获取，这里只想到遍历日期获取redis里的观看次数，然后再定义一个map集合，key = videoId， value = 总观看次数
             遍历之后可以获取短剧的总观看次数
             都是简单的crud，这里不再详细实现，所以只用了今日和昨日的数据
             */
        Map<Long, Double> hotMap = new HashMap<>();
        for (Video video : videos) {
            Long videoId = video.getId();
            Integer collectNum = yesterdayCollectMap.get(videoId);
            if (collectNum == null){
                collectNum = 0;
            }
            Integer todayCollectNum = todayCollectMap.get(videoId);
            if (todayCollectNum == null){
                todayCollectNum = 0;
            }
            Integer likedNum = yesterdayLikedMap.get(videoId);
            if (likedNum == null){
                likedNum = 0;
            }
            Integer todayLikedNum = todayLikedMap.get(videoId);
            if (todayLikedNum == null){
                todayLikedNum = 0;
            }
            Integer lookNum = yesterdayLookNumMap.get(videoId.toString());
            if (lookNum == null){
                lookNum = 0;
            }
            Integer todayLookNum = todayLookNumMap.get(videoId.toString());
            if (todayLookNum == null){
                todayLookNum = 0;
            }
            Integer todaySearchNum = searchNumMap.get(videoId.toString());
            if (todaySearchNum == null){
                todaySearchNum = 0;
            }
            soarMap.put(videoId, 0.5 * collectNum + 0.3 * likedNum + 0.2 * lookNum);
            searchMap.put(videoId, 0.4 * todaySearchNum + 0.3 * todayCollectNum + 0.2 * todayLikedNum + 0.1 * todayLookNum);
            hotMap.put(videoId, 0.5 * (collectNum + todayCollectNum) + 0.3 * (likedNum + todayLikedNum) + 0.2 * (lookNum + todayLookNum));
        }
        // 飙升榜数据存到redis里
        soarMap.forEach((k, v) -> {
            for (Video video : videos) {
                if (k.equals(video.getId())){
                    stringRedisTemplate.opsForZSet().add(RedisKey.LIST_SOAR_RESULT_KEY, JSON.toJSONString(video), v);
                }
            }
        });
        // 热搜榜数据存到redis里
        searchMap.forEach((k, v) -> {
            for (Video video : videos) {
                if (k.equals(video.getId())){
                    stringRedisTemplate.opsForZSet().add(RedisKey.LIST_SEARCH_RESULT_KEY, JSON.toJSONString(video), v);
                }
            }
        });
        // 热播榜数据存到redis里
        hotMap.forEach((k, v) -> {
            for (Video video : videos) {
                if (k.equals(video.getId())){
                    stringRedisTemplate.opsForZSet().add(RedisKey.LIST_HOT_RESULT_KEY, JSON.toJSONString(video), v);
                }
            }
        });
    }
}
